﻿using System;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.Data;
namespace PssFramework
{

    namespace PSClient
    {

        public class SubsciberEventArgs : EventArgs
        {
            public SubsciberEventArgs()
            {
            }
            public int Key;
            public byte[] mRxData;
        }
        public class Subscriber 
        {
            Socket _client;
            EndPoint _remoteEndPoint;
            byte[] _data;
            int _recv;
            Boolean _isReceivingStarted = false;
            public event EventHandler OnReceived;
            public SubsciberEventArgs mEarg = new SubsciberEventArgs();
            Thread thread1;
            int Topic;

            public Subscriber()
            {
                IPAddress serverIPAddress = IPAddress.Parse(Config.getInstance().Ip);
                _client = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                _remoteEndPoint = new IPEndPoint(serverIPAddress, Config.getInstance().SubscribePort);
            }


            public void Subscribe(int Topic)
            {
                this.Topic = Topic;
                int cmd = (int)PssFramework.EPPSCommands.SUBSCRIBE;
                int[] header = new int[] { cmd, Topic};
                byte[] txData = new byte[header.Length * 4];
                Buffer.BlockCopy(header, 0, txData, 0, txData.Length);
                _client.SendTo(txData, _remoteEndPoint);
                if (_isReceivingStarted == false)
                {
                    _isReceivingStarted = true;
                    _data = new byte[1024];
                    if (thread1 != null)
                    {
                        thread1.Join();
                    }
                    thread1 = new Thread(new ThreadStart(ReceiveDataFromServer));
                    thread1.IsBackground = true;
                    thread1.Start();
                }
            }
            public void Unsubscribe()
            {
                int cmd = (int)PssFramework.EPPSCommands.UNSUBSCRIBE;
                int[] header = new int[] { cmd, Topic };
                byte[] txData = new byte[header.Length * 4];
                Buffer.BlockCopy(header, 0, txData, 0, txData.Length);
                _client.SendTo(txData, _remoteEndPoint);
                if (thread1 != null)
                {
                    thread1.Join();
                }
            }

      

           private  void ReceiveDataFromServer()
            {
                EndPoint publisherEndPoint = _client.LocalEndPoint;
                while (true)
                {
                    _recv = _client.ReceiveFrom(_data, ref publisherEndPoint);
                    mEarg.Key = Utils.getValue(_data,0);
                    byte[] rxData = new byte[_recv-4];
                    Array.Copy(_data, 4, rxData, 0, rxData.Length);
                    mEarg.mRxData = rxData;
                    OnReceived.Invoke(this, mEarg);
                }
            }

           public void close()
           {
               Unsubscribe();
           }
            
            

        }
    }
}